package lk.icta.common.util;

import lk.icta.user.common.Permission;
import lk.icta.user.dao.RoleDAO;
import lk.icta.user.entity.Role;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;

import java.util.BitSet;

public class RolePermissionUtils {
    private static final Logger logger = LoggerFactory.getLogger(RolePermissionUtils.class);

    private static final BitSet adminBitSet;
    private static final BitSet orlmBitSet;
    private static final BitSet ordsBitSet;
    private static final BitSet loBitSet;
    private static final BitSet ormoiBitSet;
    private static final BitSet plcBitSet;
    private static final BitSet orpiiBitSet;
    private static final BitSet urmgoiBitSet;
    private static final BitSet slcBitSet;
    private static final BitSet lcgBitSet;
    private static final BitSet orlpBitSet;
    private static final BitSet paBitSet;
    private static final BitSet oripBitSet;

    private static final BitSet scBitSet;

    private static final BitSet boBitSet;
    private static final BitSet shBitSet;

    private static final BitSet sdhBitSet;
    private static final BitSet dhBitSet;

    static {
        //admin
        adminBitSet = new BitSet();
        adminBitSet.set(Permission.USER_MANAGEMENT);

        //PA
        paBitSet = new BitSet();
        paBitSet.set(Permission.USER_MANAGEMENT);

        // ORLM
        orlmBitSet = new BitSet();
        orlmBitSet.set(Permission.INITIAL_LAND_DATA_ENTRY);
        orlmBitSet.set(Permission.INITIAL_LAND_DATA_MODIFICATION);
        orlmBitSet.set(Permission.DETAIL_LAND_DATA_ENTRY);
        orlmBitSet.set(Permission.DETAIL_LAND_DATA_MODIFICATION);
        orlmBitSet.set(Permission.MANAGE_INITIAL_LAND_APPLICATION);
        orlmBitSet.set(Permission.MANAGE_DETAIL_LAND_APPLICATION);
        orlmBitSet.set(Permission.INITIAL_ALIENATION_DATA_ENTRY);
        orlmBitSet.set(Permission.INITIAL_ALIENATION_DATA_MODIFICATION);
        orlmBitSet.set(Permission.DETAIL_ALIENATION_DATA_ENTRY);
        orlmBitSet.set(Permission.DETAIL_ALIENATION_DATA_MODIFICATION);
        orlmBitSet.set(Permission.LAND_VISIT_SCHEDULE);

        // ORDS
        ordsBitSet = new BitSet();
        ordsBitSet.set(Permission.LAND_APPROVAL);
        ordsBitSet.set(Permission.ALIENATION_APPROVAL);
        ordsBitSet.set(Permission.DETAIL_LAND_DATA_MODIFICATION);
        ordsBitSet.set(Permission.APPROVE_REJECT_DETAIL_LAND_APPLICATION);
        ordsBitSet.set(Permission.APPROVE_REJECT_INITIAL_LAND_APPLICATION);
        ordsBitSet.set(Permission.MANAGE_DETAIL_LAND_APPLICATION);
        ordsBitSet.set(Permission.USER_MANAGEMENT);

        //LO
        loBitSet = new BitSet();
        loBitSet.or(orlmBitSet);
        loBitSet.set(Permission.MANAGE_INITIAL_LAND_APPLICATION);
        loBitSet.set(Permission.MANAGE_DETAIL_LAND_APPLICATION);

        //PLC
        plcBitSet = new BitSet();
        plcBitSet.set(Permission.MANAGE_DETAIL_LAND_APPLICATION);

        //OR-MOI
        ormoiBitSet = new BitSet();
        ormoiBitSet.set(Permission.MANAGE_GOVERNMENT_ORGANIZATION);
        ormoiBitSet.set(Permission.MANAGE_GOVERNMENT_ORGANIZATION_USER_PROFILE);
        ormoiBitSet.set(Permission.SCHEDULE_BRIEFING_SESSION);
        ormoiBitSet.set(Permission.USER_MANAGEMENT);

        //OR-PII
        orpiiBitSet = new BitSet();
        orpiiBitSet.set(Permission.USER_MANAGEMENT);
        orpiiBitSet.set(Permission.MANAGE_GOVERNMENT_ORGANIZATION_USER_PROFILE);
        orpiiBitSet.set(Permission.MANAGE_GOVERNMENT_ORGANIZATION);

        //OR-MGOI
        urmgoiBitSet = new BitSet();
        urmgoiBitSet.set(Permission.MANAGE_GOVERNMENT_ORGANIZATION_USER_PROFILE);

        //SLC
        slcBitSet = new BitSet();
        slcBitSet.set(Permission.MANAGE_DETAIL_LAND_APPLICATION);

        //LCG
        lcgBitSet = new BitSet();
        lcgBitSet.set(Permission.APPROVE_REJECT_DETAIL_LAND_APPLICATION);
        lcgBitSet.set(Permission.MANAGE_DETAIL_LAND_APPLICATION);

        //ORLP
        orlpBitSet = new BitSet();
        orlpBitSet.set(Permission.APPROVE_REJECT_DETAIL_LAND_APPLICATION);

        //ORIP
        oripBitSet = new BitSet();
        oripBitSet.or(loBitSet);
        oripBitSet.or(ordsBitSet);

        ////// eRail ////////

        //SC
        scBitSet = new BitSet();
        scBitSet.or(loBitSet);

        //BO
        boBitSet = new BitSet();
        boBitSet.or(ordsBitSet);

        //SH
        shBitSet = new BitSet();
        shBitSet.or(boBitSet);

        //SDH
        sdhBitSet = new BitSet();
        sdhBitSet.or(oripBitSet);

        //DH
        dhBitSet = new BitSet();
        dhBitSet.or(sdhBitSet);

    }

    public static void setPermissionBits(ApplicationContext ctx) {
        try {
            // ---------------- populate permissions ---------------------
            RoleDAO roleDao = (RoleDAO) ctx.getBean("roleDAO", RoleDAO.class);

            Role deoRole = roleDao.getRole("ADMIN");
            deoRole.setPermBitSet(adminBitSet);
            roleDao.save(deoRole);

            /*Role paRole = roleDao.getRole("PA");
            paRole.setPermBitSet(paBitSet);
            roleDao.save(paRole);

            Role orlmRole = roleDao.getRole("ORLM");
            orlmRole.setPermBitSet(orlmBitSet);
            roleDao.save(orlmRole);

            Role ordsRole = roleDao.getRole("ORDS");
            ordsRole.setPermBitSet(ordsBitSet);
            roleDao.save(ordsRole);

            Role loRole = roleDao.getRole("LO");
            loRole.setPermBitSet(loBitSet);
            roleDao.save(loRole);

            Role ormoiRole = roleDao.getRole("ORMOI");
            ormoiRole.setPermBitSet(ormoiBitSet);
            roleDao.save(ormoiRole);

            Role orpiiRole = roleDao.getRole("ORPII");
            orpiiRole.setPermBitSet(orpiiBitSet);
            roleDao.save(orpiiRole);

            Role urmgoiRole = roleDao.getRole("URMGOI");
            urmgoiRole.setPermBitSet(urmgoiBitSet);
            roleDao.save(urmgoiRole);

            Role plcRole = roleDao.getRole("PLC");
            plcRole.setPermBitSet(plcBitSet);
            roleDao.save(plcRole);

            Role slcRole = roleDao.getRole("SLC");
            slcRole.setPermBitSet(slcBitSet);
            roleDao.save(slcRole);

            Role lcgRole = roleDao.getRole("LCG");
            lcgRole.setPermBitSet(lcgBitSet);
            roleDao.save(lcgRole);

            Role orlpRole = roleDao.getRole("ORLP");
            orlpRole.setPermBitSet(orlpBitSet);
            roleDao.save(orlpRole);

            Role oripRole = roleDao.getRole("ORIP");
            oripRole.setPermBitSet(oripBitSet);
            roleDao.save(oripRole);*/

            // eRail users
            Role scRole = roleDao.getRole("SC");
            scRole.setPermBitSet(scBitSet);
            roleDao.save(scRole);

            Role boRole = roleDao.getRole("BO");
            boRole.setPermBitSet(boBitSet);
            roleDao.save(boRole);

            Role shRole = roleDao.getRole("SH");
            shRole.setPermBitSet(shBitSet);
            roleDao.save(shRole);

            Role sdhRole = roleDao.getRole("SDH");
            sdhRole.setPermBitSet(sdhBitSet);
            roleDao.save(sdhRole);

            Role dhRole = roleDao.getRole("DH");
            dhRole.setPermBitSet(dhBitSet);
            roleDao.save(dhRole);


            logger.info("Initialized the database by performing permission initialization");

        } catch (Exception e) {
            logger.error("Error initializing role permissions on the database");
            throw new IllegalStateException("Error initializing role permissions. See log for details", e);
        }
    }
}
